
#ifndef ROPUFU_WINDOW_NONE_HPP_INCLUDED
#define ROPUFU_WINDOW_NONE_HPP_INCLUDED

#include <array>
#include <cstdint>
#include <ostream>
#include <string>

namespace ropufu
{
    template <std::size_t t_count_streams>
    struct window_none
    {
        static const std::size_t count_streams = t_count_streams;
        typedef window_none<count_streams> type;

    private:
        std::size_t m_time = 0UL;
        std::array<double, count_streams> m_loglikelihood_latest;
        std::array<double, count_streams> m_loglikelihood_accumulated;

    public:
        explicit window_none()
        {
            this->reset();
        }

        void reset()
        {
            this->m_time = 0UL;
            this->m_loglikelihood_latest.fill(0.0);
            this->m_loglikelihood_accumulated.fill(0.0);
        }

        std::size_t get_depth() const
        {
            return 1UL;
        }

        void observe(const std::array<double, count_streams>& loglikelihood)
        {
            this->m_loglikelihood_latest = loglikelihood;
            for (std::size_t k = 0; k < count_streams; k++) this->m_loglikelihood_accumulated[k] += loglikelihood[k];
            this->m_time++;
        }

        // Returns the complete loglikelihood ratio.
        const std::array<double, count_streams>& complete() const
        {
            return this->m_loglikelihood_accumulated;
        }

        // Returns the accumulated loglikelihood ratio.
        const std::array<double, count_streams>& accumulated() const
        {
            return this->m_loglikelihood_accumulated;
        }

        // Returns the history of observations since the last reset.
        const std::array<double, count_streams>& get_history() const
        {
            return this->m_loglikelihood_latest;
        }

        double get_history_at(std::size_t stream_index, std::size_t time_index) const
        {
            return this->m_loglikelihood_latest[stream_index];
        }

        friend std::ostream& operator <<(std::ostream& os, const type& that)
        {
            return os << "window_none";
        }
    };
}

#endif // ROPUFU_WINDOW_NONE_HPP_INCLUDED
